package cn.huiyunche.bms.backend.service;

import cn.huiyunche.bms.backend.bo.PayableBillBO;
import cn.huiyunche.bms.backend.bo.PaymentBO;
import cn.huiyunche.bms.backend.constant.AutoConfConstant;
import cn.huiyunche.bms.backend.enums.BillStatusEnum;
import cn.huiyunche.bms.backend.enums.PayStatusEnum;
import cn.huiyunche.bms.backend.query.PayableBillConditions;
import cn.huiyunche.bms.backend.query.WayBillDetailConditions;
import cn.huiyunche.bms.backend.util.PoiUtil;
import cn.huiyunche.bms.backend.util.UniquenessUtil;
import cn.huiyunche.bms.base.mapper.*;
import cn.huiyunche.bms.base.model.*;
import cn.huiyunche.commons.domain.PageVo;
import cn.huiyunche.commons.exception.BusinessException;
import cn.huiyunche.commons.utils.HttpRequestUtil;
import com.alibaba.fastjson.JSONObject;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.poi.hssf.usermodel.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.servlet.http.HttpServletResponse;
import javax.swing.*;
import java.io.*;
import java.math.BigDecimal;
import java.net.URLEncoder;
import java.text.SimpleDateFormat;
import java.util.*;

/**
 * Created by Administrator on 2017/7/6 0006.
 */
@Service
public class PayableServiceImpl implements PayableService {
    private static final Logger LOGGER = LoggerFactory.getLogger(PayableServiceImpl.class);


    @Autowired
    private BmsPayableBillMapper bmsPayableBillMapper;

    @Autowired
    private BmsPayableFeeDetailTempMapper bmsPayableFeeDetailTempMapper;

    @Autowired
    private BmsPayableFeeDetailMapper bmsPayableFeeDetailMapper;

    @Autowired
    private CWaybillDetailMapper cWaybillDetailMapper;

    @Autowired
    private CWaybillMapper cWaybillMapper;

    @Autowired
    private AreaService areaService;

    @Autowired
    private AutoConfConstant autoConfConstant;
    @Override
    public Map<String, Object> selectListByConditions(PageVo pageVo, PayableBillConditions conditions) throws Exception {
        LOGGER.info("PayableServiceImpl.selectListByConditions params : {}, {}", pageVo, conditions);

        if (null == conditions) {
            LOGGER.error("PayableServiceImpl.selectListByConditions param conditions must not be null");
            throw new IllegalArgumentException("查询条件不能为空!");
        }

        Map<String, Object> map = new HashMap<>();

        String orderByClause = null;
        if (null != pageVo) {
            orderByClause = StringUtils.isNotBlank(pageVo.getOrder()) == true ? pageVo.getOrder() : " id DESC";
        }

        BmsPayableBillExample example = new BmsPayableBillExample();
        BmsPayableBillExample.Criteria criteria = example.createCriteria();
        //账单编号
        if (null != conditions.getBillCode()) {
            criteria.andBillCodeEqualTo(conditions.getBillCode());
        }
        //承运方
        if (null != conditions.getCarrierId()) {
            criteria.andCarrierIdEqualTo(conditions.getCarrierId());
        }
        if (null != conditions.getCarrierName()) {
            criteria.andCarrierNameEqualTo(conditions.getCarrierName());
        }
        //账单状态
        if (null != conditions.getBillStatus()) {
            criteria.andBillStatusEqualTo(conditions.getBillStatus());
        }
        //账单日期
        SimpleDateFormat sim = new SimpleDateFormat("yyyy-MM-dd");
        if (null != conditions.getBillDateStart()) {
            criteria.andBillDateGreaterThanOrEqualTo(sim.parse(conditions.getBillDateStart()));
        }
        if (null != conditions.getBillDateEnd()) {
            criteria.andBillDateLessThanOrEqualTo(sim.parse(conditions.getBillDateEnd()));
        }

        if (null != pageVo) {
            pageVo.setTotalRecord(bmsPayableBillMapper.countByExample(example));
            example.setLimitStart(pageVo.getStartIndex());
            example.setLimitEnd(pageVo.getPageSize());
            example.setOrderByClause(orderByClause);
        }

        List<BmsPayableBill> list = bmsPayableBillMapper.selectByExample(example);
        map.put("list", list);

        List<PayableFeeDetailViewDAO> nameList = null;
        try {
            nameList = cWaybillDetailMapper.selectNameByBidderId();
        } catch (Exception e) {
            LOGGER.error("PayableServiceImpl.listWaybillDetail error: {}", e);
            throw new BusinessException("查询所有承运人异常");
        }

        if(CollectionUtils.isNotEmpty(nameList)){
            map.put("carrierList", nameList);
        }

        if (null != pageVo) {
            map.put("page", pageVo);
        }

        return map;
    }

    @Override
    public BmsPayableFeeDetailTemp getAlterCost(Integer id) {
        LOGGER.info("PayableServiceImpl.getAlterCost param : {}", id);

        if (id == null) {
            LOGGER.error("PayableServiceImpl.getAlterCost param  must not be null ");
            throw new IllegalArgumentException("ID不能为空");
        }
        return bmsPayableFeeDetailTempMapper.selectByPrimaryKey(id);
    }

    @Override
    public int updateAlterCost(PayableBillBO payableBillBO) {
        LOGGER.info("PayableServiceImpl.updateAlterCost params : {}", payableBillBO);

        if (null == payableBillBO) {
            LOGGER.error("PayableServiceImpl.updateAlterCost param form must not be null ");
            throw new IllegalArgumentException("数据不能为空");
        }

        BmsPayableFeeDetailTemp bmsPayableFeeDetailTemp = new BmsPayableFeeDetailTemp();
        BeanUtils.copyProperties(payableBillBO, bmsPayableFeeDetailTemp);

        return bmsPayableFeeDetailTempMapper.updateByPrimaryKeySelective(bmsPayableFeeDetailTemp);
    }

    @Override
    public int deletePayableFeeDetailTemp(Integer id) {
        LOGGER.info("PayableServiceImpl.deletePayableFeeDetailTemp params : {}", id);

        if (null == id) {
            LOGGER.error("PayableServiceImpl.deletePayableFeeDetailTemp param form must not be null ");
            throw new IllegalArgumentException("不能为空");
        }

        return bmsPayableFeeDetailTempMapper.deleteByPrimaryKey(id);
    }

    @Override
    public int generateBill(String versionNo, String invoiceStatus, String username) {
        LOGGER.info("PayableServiceImpl.generateBill params : {}", versionNo, invoiceStatus, username);

        if (StringUtils.isEmpty(versionNo)) {
            LOGGER.error("PayableServiceImpl.generateBill param versionNo must not be null ");
            throw new IllegalArgumentException("数据不能为空");
        }
        if (StringUtils.isEmpty(invoiceStatus)) {
            LOGGER.error("PayableServiceImpl.generateBill param invoiceStatus must not be null ");
            throw new IllegalArgumentException("数据不能为空");
        }
        //根据前台传过来的版本号查询当前版本号对应数据 ps:查询到所有和应付账单表相关的数据
        List<PayableFeeDetailViewDAO> payableFeeDetailViewDAOS = bmsPayableFeeDetailTempMapper.selectPayableFeeDetailTemp(versionNo);
        HashSet<Integer> set = new HashSet<>();
        for (PayableFeeDetailViewDAO temp : payableFeeDetailViewDAOS) {
            set.add(temp.getCarrierId());
        }
        Iterator<Integer> it = set.iterator();
        while (it.hasNext()) {
            Integer carrierId = it.next();
            List<PayableFeeDetailViewDAO> list = new ArrayList<>();
            for (PayableFeeDetailViewDAO temp : payableFeeDetailViewDAOS) {
                if (temp.getCarrierId().equals(carrierId)) {
                    list.add(temp);
                }
            }
            BmsPayableBill bill = new BmsPayableBill();
            String billCode = UniquenessUtil.generateUniquenessFlag("BP");
            bill.setBillCode(billCode);
            bill.setBillDate(new Date());
            bill.setCarrierId(list.get(0).getCarrierId());
            bill.setCarrierName(list.get(0).getCarrierName());
            bill.setPayeeId(list.get(0).getCarrierId());
            bill.setPayeeName(list.get(0).getCarrierName());
            //需要调整 7-15记录
            //-------------
            if(list.get(0).getConsignorId()!=null){
                bill.setConsignorId(list.get(0).getConsignorId());
            }else{
                bill.setConsignorId(132);
            }
            if(list.get(0).getConsignorName()!=null){
                bill.setConsignorName(list.get(0).getConsignorName());
            }else{
                bill.setConsignorName("中联新渠道");
            }
            //--------------
            bill.setPayerId(132);
            bill.setPayerName("中联新渠道");

            bill.setBillStatus(BillStatusEnum.NOCHECK.getValue());
            bill.setInvoiceStatus(invoiceStatus);
            bill.setCreateUser(username);
            bill.setGoodsSum(BigDecimal.valueOf(list.size()));

            BigDecimal sysCost = new BigDecimal(0);
            for (PayableFeeDetailViewDAO wBill : list) {
                if (wBill.getSysCost() != null) {
                    sysCost = sysCost.add(new BigDecimal(wBill.getSysCost().toString()));
                }
            }
            bill.setWaybillCost(sysCost);

            BigDecimal alterCost = new BigDecimal(0);
            for (PayableFeeDetailViewDAO wBill : list) {
                if (wBill.getAlterCost() != null) {
                    alterCost = alterCost.add(new BigDecimal(wBill.getAlterCost().toString()));
                }
            }
            bill.setAlterCost(alterCost);

            BigDecimal settleCost = new BigDecimal(0);
            for (PayableFeeDetailViewDAO wBill : list) {
                if (wBill.getSettleCost() != null) {
                    settleCost = settleCost.add(new BigDecimal(wBill.getSettleCost().toString()));
                }
            }
            bill.setSettleCost(settleCost);

            try {
                bmsPayableBillMapper.insertSelective(bill);
            } catch (Exception e) {
                LOGGER.error("PayableServiceImpl.insertSelective  error: {}", e);
                throw new BusinessException("数据插入账单表异常");
            }

            BmsPayableBillExample example = new BmsPayableBillExample();
            example.createCriteria().andBillCodeEqualTo(billCode);
            List<BmsPayableBill> bills = bmsPayableBillMapper.selectByExample(example);
            for (PayableFeeDetailViewDAO temp : list) {
                BmsPayableFeeDetail detail = new BmsPayableFeeDetail();
                BeanUtils.copyProperties(temp, detail);
                detail.setBillId(bills.get(0).getId());
                detail.setFeeSource("10");
                detail.setFeeTypeCode("40");
                detail.setFeeTypeName("运输费");
                detail.setCreateUser(username);
                try {
                    bmsPayableFeeDetailMapper.insertSelective(detail);
                } catch (Exception e) {
                    LOGGER.error("PayableServiceImpl.insertSelective  error: {}", e);
                    throw new BusinessException("数据插入应付费用明细表异常");
                }
            }
            BmsPayableFeeDetailTempExample example1 = new BmsPayableFeeDetailTempExample();
            example1.createCriteria().andVersionNoEqualTo(versionNo);
            //生成账单后将临时表数据清除
            bmsPayableFeeDetailTempMapper.deleteByExample(example1);
        }
        return 0;
    }

    @Override
    public void deletePayable(List ids) {
        LOGGER.info("PayableServiceImpl.deletePayable params : {}", ids);

        if (CollectionUtils.isNotEmpty(ids)) {
            for (int i = 0; i < ids.size(); i++) {

                //根据账单id删除账单表数据
                bmsPayableBillMapper.deleteByPrimaryKey((Integer) ids.get(i));

                BmsPayableFeeDetailExample example = new BmsPayableFeeDetailExample();
                example.createCriteria().andBillIdEqualTo((Integer) ids.get(i));
                //根据账单id删除 详情表数据
                bmsPayableFeeDetailMapper.deleteByExample(example);
            }
        } else {
            LOGGER.error("PayableServiceImpl.deletePayable param form must not be null ");
            throw new IllegalArgumentException("数据不能为空");
        }
    }


    @Override
    public Map<String, Object> confirmPayableBill(Integer id, PageVo pageVo) {
        LOGGER.info("PayableServiceImpl.confirmPayableBill params : {}, {}", id, pageVo);

        if (null == id) {
            LOGGER.error("PayableServiceImpl.confirmPayableBill param  must not be null");
            throw new IllegalArgumentException("id不能为空!");
        }
        // 构建查询条件
        Map<String, Object> queryMap = new HashMap<String, Object>();
        queryMap.put("billId", id);

        // 统计记录数
        try {
            pageVo.setTotalRecord(bmsPayableFeeDetailMapper.countPayableFeeDetail(queryMap));
        } catch (Exception e) {
            LOGGER.error("PayableServiceImpl.countPayableFeeDetail TotalRecord error: {}", e);
            throw new BusinessException("统计纪录数异常");
        }

        // 返回值
        Map<String, Object> map = new HashMap<>();
        if (!Objects.equals(pageVo, null) && !Objects.equals(pageVo, "")) {
            queryMap.put("orderByClause", StringUtils.isNotBlank(pageVo.getOrder()) == true ? pageVo.getOrder() : "bpf.id desc");
            queryMap.put("limitStart", pageVo.getStartIndex());
            queryMap.put("limitEnd", pageVo.getPageSize());
            map.put("page", pageVo);
        }

        // 查询数据
        List<PayableFeeDetailViewDAO> payableFeeDetails = null;
        try {
            payableFeeDetails = bmsPayableFeeDetailMapper.listPayableFeeDetails(queryMap);
        } catch (Exception e) {
            LOGGER.error("PayableServiceImpl.listPayableFeeDetails error: {}", e);
            throw new BusinessException("确认明细查询信息异常");
        }
        map.put("list", payableFeeDetails);

        BmsPayableBill   bill  = bmsPayableBillMapper.selectByPrimaryKey(id);

        map.put("bill", bill);

        return map;
    }

    @Override
    public int deletePayableFeeDetail(Integer id ) {
        LOGGER.info("PayableServiceImpl.deletePayableFeeDetail params : {}", id);

        if (null == id) {
            LOGGER.error("PayableServiceImpl.deletePayableFeeDetail param id must not be null ");
            throw new IllegalArgumentException("不能为空");
        }

        //根据详情id查询 要删除的对象 取账单id
        BmsPayableFeeDetail bmsPayableFeeDetail = null;
        try {
            bmsPayableFeeDetail = bmsPayableFeeDetailMapper.selectByPrimaryKey(id);
        } catch (Exception e) {
            LOGGER.error("PayableServiceImpl.selectByPrimaryKey error: {}", e);
            throw new BusinessException("查询费用详情异常");
        }

        //移除费用详情数据
        try {
            bmsPayableFeeDetailMapper.deleteByPrimaryKey(id);
        } catch (Exception e) {
            LOGGER.error("PayableServiceImpl.deletePayableFeeDetail error: {}", e);
            throw new BusinessException("移除费用详情异常");
        }

        //根据账单id 查询当前账单费用明细金额总和
        PayableFeeDetailViewDAO feeDetail = null;
        try {
            feeDetail = bmsPayableFeeDetailMapper.selectSumCost(bmsPayableFeeDetail.getBillId());
        } catch (Exception e) {
            LOGGER.error("PayableServiceImpl.selectSumCost error: {}", e);
            throw new BusinessException("根据账单id查询费用详情的费用总和异常");
        }

        if(feeDetail == null){
            //如果查询到的费用明细总金额为空，说明此费用明细是最后一条数据，账单没有存在的意义。删除账单
            bmsPayableBillMapper.deleteByPrimaryKey(bmsPayableFeeDetail.getBillId());
        } else {
            //如果当前账单费用明细不为空，将账单金额修改
            BmsPayableBill bill = new BmsPayableBill();
            bill.setId(bmsPayableFeeDetail.getBillId());
            bill.setWaybillCost(feeDetail.getSysCost());
            bill.setAlterCost(feeDetail.getAlterCost());
            bill.setSettleCost(feeDetail.getSettleCost());
            bill.setGoodsSum(BigDecimal.valueOf(feeDetail.getGoodsSum()));
            //修改账单表费用信息
            bmsPayableBillMapper.updateByPrimaryKeySelective(bill);
        }
        return 0;
    }

    @Override
    public BmsPayableFeeDetail getPayableFeeDetail(Integer id) {
        LOGGER.info("PayableServiceImpl.getPayableFeeDetail param : {}", id);

        if (id == null) {
            LOGGER.error("PayableServiceImpl.getPayableFeeDetail param  must not be null ");
            throw new IllegalArgumentException("ID不能为空");
        }
        return bmsPayableFeeDetailMapper.selectByPrimaryKey(id);
    }

    @Override
    public int updatePayableFeeDetail(PayableBillBO payableBillBO) {
        LOGGER.info("PayableServiceImpl.updatePayableFeeDetail params : {}", payableBillBO);

        if (null == payableBillBO) {
            LOGGER.error("PayableServiceImpl.updatePayableFeeDetail param form must not be null ");
            throw new IllegalArgumentException("数据不能为空");
        }
        //根据id修改费用详细调整金额  结算金额 ,运单金额，备注
        BmsPayableFeeDetail feeDetail = new BmsPayableFeeDetail();
        BeanUtils.copyProperties(payableBillBO, feeDetail);
        try {
            bmsPayableFeeDetailMapper.updateByPrimaryKeySelective(feeDetail);
        } catch (Exception e) {
            LOGGER.error("PayableServiceImpl.updateByPrimaryKeySelective param error: {}", e);
            throw new IllegalArgumentException("修改费用详情调整金额,结算金额异常");
        }

        //根据费用详情id 查询费用信息取billId
        BmsPayableFeeDetail bmsPayableFeeDetail = null;
        try {
            bmsPayableFeeDetail = bmsPayableFeeDetailMapper.selectByPrimaryKey(feeDetail.getId());
        } catch (Exception e) {
            LOGGER.error("PayableServiceImpl.selectByPrimaryKey error: {}", e);
            throw new IllegalArgumentException("查询费用详情信息异常");
        }

        //根据账单id(billId) 查询当前账单详情金额总和
        PayableFeeDetailViewDAO fee = null;
        try {
            fee = bmsPayableFeeDetailMapper.selectSumCost(bmsPayableFeeDetail.getBillId());
        } catch (Exception e) {
            LOGGER.error("PayableServiceImpl.selectSumCost error: {}", e);
            throw new BusinessException("根据账单id查询费用详情的费用总和异常");
        }

        BmsPayableBill bill = new BmsPayableBill();
        bill.setId(bmsPayableFeeDetail.getBillId());
        bill.setComment(bmsPayableFeeDetail.getComment());
        bill.setWaybillCost(fee.getSysCost());
        bill.setAlterCost(fee.getAlterCost());
        bill.setSettleCost(fee.getSettleCost());

        //修改账单表费用信息
        try {
            bmsPayableBillMapper.updateByPrimaryKeySelective(bill);
        } catch (Exception e) {
            LOGGER.error("PayableServiceImpl.updateByPrimaryKeySelective error: {}", e);
            throw new IllegalArgumentException("修改账单调整金额,结算金额异常");
        }
        return 0;
    }

    @Override
    public int createPayableBill(String invoiceStatus, Integer billId) throws Exception {
        if (null == invoiceStatus) {
            LOGGER.error("PayableServiceImpl.createPayableBill param form must not be null ");
            throw new IllegalArgumentException("开票状态不能为空");
        }
        if (null == billId) {
            LOGGER.error("PayableServiceImpl.createPayableBill param form must not be null ");
            throw new IllegalArgumentException("应付账单ID不能为空");
        }

        //根据应付账单ID,将发票状态传入账单表中,确认账单，将账单状态改为已确认
        BmsPayableBill bmsPayableBill = new BmsPayableBill();
        bmsPayableBill.setId(billId);
        bmsPayableBill.setInvoiceStatus(invoiceStatus);
        //账单已确认
        bmsPayableBill.setBillStatus(BillStatusEnum.CHECKED.getValue());
        bmsPayableBillMapper.updateByPrimaryKeySelective(bmsPayableBill);
        //账单放入单据池
        BmsPayableBill bill1 = bmsPayableBillMapper.selectByPrimaryKey(billId);
        String url = autoConfConstant.getOperation()+ "/api/bms/bill/addPayableBill";
        Integer time = autoConfConstant.getOperationTime();
        Map<String, Object> map = new HashMap<>();
        map.put("payableBillCode", bill1.getBillCode());
        String result = HttpRequestUtil.sendHttpPost(url, map, time);
        if (!Objects.equals(result, null)) {
            JSONObject jsonObject = JSONObject.parseObject(result);
            String msgCode = jsonObject.getString("messageCode");
            String msg = jsonObject.getString("message");
//            String data = jsonObject.getString("data");
            Boolean success = jsonObject.getBoolean("success");
            if (!success) {
                LOGGER.error("PayableServiceImpl addPayableBill result error");
                throw new BusinessException(msgCode, msg);
            }else {
                LOGGER.info("PayableServiceImpl addPayableBill result success");
            }
        }
        return 0;
    }


    @Override
    public Map<String, Object> selectWaybillDetaiByConditions(PageVo pageVo, WayBillDetailConditions conditions) throws Exception {
        LOGGER.info("PayableServiceImpl.selectWaybillDetaiByConditions params : {}, {}", pageVo, conditions);

        if (null == conditions) {
            LOGGER.error("PayableServiceImpl.selectWaybillDetaiByConditions param conditions must not be null");
            throw new IllegalArgumentException("查询条件不能为空!");
        }

        // 构建查询条件
        Map<String, Object> queryMap = new HashMap<String, Object>();
        queryMap.put("bidderId", conditions.getBidderId());
        queryMap.put("status", conditions.getStatus());
        queryMap.put("departProvinceCode", conditions.getDepartProvinceCode());
        queryMap.put("departCityCode", conditions.getDepartCityCode());
        queryMap.put("departCountyCode", conditions.getDepartCountyCode());
        queryMap.put("receiptProvinceCode", conditions.getReceiptProvinceCode());
        queryMap.put("receiptCityCode", conditions.getReceiptCityCode());
        queryMap.put("receiptCountyCode", conditions.getReceiptCountyCode());
        queryMap.put("createTimeStart", conditions.getCreateTimeStart());
        queryMap.put("createTimeEnd", conditions.getCreateTimeEnd());
        queryMap.put("waybillCode", conditions.getWaybillCode());
        return buildListWaybillDetai(queryMap, pageVo);
    }


    private Map<String, Object> buildListWaybillDetai(Map<String, Object> queryMap, PageVo pageVo) {

        // 统计记录数
        try {
            pageVo.setTotalRecord(cWaybillDetailMapper.countWaybillDetail(queryMap));
        } catch (Exception e) {
            LOGGER.error("PayableServiceImpl.countWaybillDetail TotalRecord error: {}", e);
            throw new BusinessException("统计纪录数异常");
        }

        // 返回值
        Map<String, Object> map = new HashMap<>();
        if (!Objects.equals(pageVo, null) && !Objects.equals(pageVo, "")) {
            queryMap.put("orderByClause", StringUtils.isNotBlank(pageVo.getOrder()) == true ? pageVo.getOrder() : "cwd.id desc");
            queryMap.put("limitStart", pageVo.getStartIndex());
            queryMap.put("limitEnd", pageVo.getPageSize());
            map.put("page", pageVo);
        }
        // 查询数据
        List<PayableFeeDetailViewDAO> waybillDetails = null;
        try {
            waybillDetails = cWaybillDetailMapper.listWaybillDetail(queryMap);
        } catch (Exception e) {
            LOGGER.error("PayableServiceImpl.listWaybillDetail error: {}", e);
            throw new BusinessException("查询信息异常");
        }
        List<PayableFeeDetailViewDAO> nameList = null;
        try {
            nameList = cWaybillDetailMapper.selectNameByBidderId();
        } catch (Exception e) {
            LOGGER.error("PayableServiceImpl.listWaybillDetail error: {}", e);
            throw new BusinessException("查询所有承运人异常");
        }

        List<BArea> areaList = null;
        try {
            areaList = areaService.queryProvince();
        } catch (Exception e) {
            LOGGER.error("PayableServiceImpl.queryProvince error: {}", e);
            throw new BusinessException("查询区域异常");
        }
        map.put("waybillDetailList", waybillDetails);
        map.put("carrierList", nameList);
        map.put("areaList", areaList);
        return map;
    }

    /**
     * WaybillDetailDAO 转换 WaybillDetailBO
     *
     * @param
     * @return
     */
//    private List<WaybillDetailBO> buildWaybillDetail(List<PayableFeeDetailViewDAO> cWaybillDetails) {
//        if (CollectionUtils.isNotEmpty(cWaybillDetails)) {
//            List<WaybillDetailBO> waybillDetailBOS = Lists.newArrayList();
//            cWaybillDetails.stream().forEach(val -> {
//                WaybillDetailBO bo = new WaybillDetailBO();
//                BeanUtils.copyProperties(val, bo);
//            });
//            return waybillDetailBOS;
//        }
//        return null;
//    }


//    @Override
//    public Map<String, Object> selectWaybillDetaiByIds(String ids) {
//        LOGGER.info("PayableServiceImpl.selectWaybillDetaiByIds params : {}", ids);
//        if (StringUtils.isEmpty(ids)) {
//            LOGGER.error("PayableServiceImpl.selectWaybillDetaiByIds param ids must not be null ");
//            throw new IllegalArgumentException("ids不能为空");
//        }
//        // 返回值
//        Map<String, Object> map = new HashMap<>();
//
//        //将ids 转化为id集合
//        List params = getIds(ids);
//
//        List<PayableFeeDetailViewDAO> waybillDetailViewDAOS = null;
//        try {
//            waybillDetailViewDAOS = cWaybillDetailMapper.selectWaybillDetailByIds(params);
//        } catch (Exception e) {
//            LOGGER.error("PayableServiceImpl.selectWaybillDetailByIds error: {}", e);
//            throw new IllegalArgumentException("查询运单详细信息异常");
//        }
//        String  versionNo = null;
//        //生成版本号
//        versionNo = UniquenessUtil.generateUniquenessFlag("BP");
//
//        if(CollectionUtils.isNotEmpty(waybillDetailViewDAOS)){
//            for (int i = 0; i<waybillDetailViewDAOS.size() ; i++) {
//                BmsPayableFeeDetailTemp bmsPayableFeeDetailTemp = new BmsPayableFeeDetailTemp();
//                BeanUtils.copyProperties(waybillDetailViewDAOS.get(i), bmsPayableFeeDetailTemp);
//                bmsPayableFeeDetailTemp.setVersionNo(versionNo);
//                bmsPayableFeeDetailTemp.setWaybillDetailId(waybillDetailViewDAOS.get(i).getWaybillDetailId());
//                bmsPayableFeeDetailTemp.setFeeSource("10");
//                bmsPayableFeeDetailTemp.setFeeTypeCode("40");
//                bmsPayableFeeDetailTemp.setFeeTypeName("运输费");
//                bmsPayableFeeDetailTemp.setConsignorId(132);
//                bmsPayableFeeDetailTemp.setConsignorName("中联新渠道");
//                bmsPayableFeeDetailTemp.setFeeDate(new Date());
//                bmsPayableFeeDetailTemp.setSettleCost(waybillDetailViewDAOS.get(i).getSysCost());
//                bmsPayableFeeDetailTemp.setAlterCost(new BigDecimal("0"));
//                //将订单详情相关数据插入到费用临时表中
//                try {
//                    bmsPayableFeeDetailTempMapper.insertSelective(bmsPayableFeeDetailTemp);
//                } catch (Exception e) {
//                    LOGGER.error("PayableServiceImpl.generateUniquenessFlag error: {}", e);
//                    throw new IllegalArgumentException("信息插入临时表异常");
//                }
//            }
//        }
//        //查询临时表相关数据并展示
//        List<PayableFeeDetailViewDAO> payableFeeDetailViewDAOS = null;
//        try {
//            payableFeeDetailViewDAOS = bmsPayableFeeDetailTempMapper.selectPayableFeeDetailTemp(versionNo);
//        } catch (Exception e) {
//            LOGGER.error("PayableServiceImpl.selectPayableFeeDetailTemp error: {}", e);
//            throw new IllegalArgumentException("根据版本号查询临时表异常");
//        }
//        map.put("list" , payableFeeDetailViewDAOS);
//        return  map;
//    }
    @Override
    public String insertTemp(List ids) {
        LOGGER.info("PayableServiceImpl.insertTemp params : {}", ids);
        if (ids.size() < 0) {
            LOGGER.error("PayableServiceImpl.insertTemp param ids must not be null ");
            throw new IllegalArgumentException("ids不能为空");
        }

        List<PayableFeeDetailViewDAO> payableFeeDetailViewDAOS = null;
        try {
            payableFeeDetailViewDAOS = cWaybillDetailMapper.selectWaybillDetailByIds(ids);
        } catch (Exception e) {
            LOGGER.error("PayableServiceImpl.selectWaybillDetailByIds error: {}", e);
            throw new IllegalArgumentException("查询运单详细信息异常");
        }
        //生成版本号
        String versionNo = UniquenessUtil.generateUniquenessFlag("BP");

        if (CollectionUtils.isNotEmpty(payableFeeDetailViewDAOS)) {
            for (int i = 0; i < payableFeeDetailViewDAOS.size(); i++) {
                BmsPayableFeeDetailTemp bmsPayableFeeDetailTemp = new BmsPayableFeeDetailTemp();
                BeanUtils.copyProperties(payableFeeDetailViewDAOS.get(i), bmsPayableFeeDetailTemp);
                bmsPayableFeeDetailTemp.setVersionNo(versionNo);
                bmsPayableFeeDetailTemp.setWaybillDetailId(payableFeeDetailViewDAOS.get(i).getWaybillDetailId());
                bmsPayableFeeDetailTemp.setFeeSource("10");
                bmsPayableFeeDetailTemp.setFeeTypeCode("40");
                bmsPayableFeeDetailTemp.setFeeTypeName("运输费");
                bmsPayableFeeDetailTemp.setConsignorId(132);
                bmsPayableFeeDetailTemp.setConsignorName("中联新渠道");
                bmsPayableFeeDetailTemp.setFeeDate(new Date());
                bmsPayableFeeDetailTemp.setSettleCost(payableFeeDetailViewDAOS.get(i).getSysCost());
                bmsPayableFeeDetailTemp.setAlterCost(new BigDecimal("0"));
                //将订单详情相关数据插入到费用临时表中
                try {
                    bmsPayableFeeDetailTempMapper.insertSelective(bmsPayableFeeDetailTemp);
                } catch (Exception e) {
                    LOGGER.error("PayableServiceImpl.generateUniquenessFlag error: {}", e);
                    throw new IllegalArgumentException("信息插入临时表异常");
                }
            }
        }
        return versionNo;
    }

    @Override
    public Map<String, Object> selectTempListByVersionNo(String versionNo) {

        LOGGER.info("PayableServiceImpl.selectTempListByVersionNo params : {}", versionNo);
        if (versionNo == null) {
            LOGGER.error("PayableServiceImpl.insertTemp param ids must not be null ");
            throw new IllegalArgumentException("版本号不能为空");
        }
        Map<String, Object> map = new HashMap<>();

        //查询临时表相关数据并展示
        List<PayableFeeDetailViewDAO> payableFeeDetailViewDAOS = null;
        try {
            payableFeeDetailViewDAOS = bmsPayableFeeDetailTempMapper.selectPayableFeeDetailTemp(versionNo);
        } catch (Exception e) {
            LOGGER.error("PayableServiceImpl.selectPayableFeeDetailTemp error: {}", e);
            throw new IllegalArgumentException("根据版本号查询临时表异常");
        }
        map.put("list", payableFeeDetailViewDAOS);

        if (CollectionUtils.isNotEmpty(payableFeeDetailViewDAOS)) {
            PayableFeeDetailViewDAO temp = bmsPayableFeeDetailTempMapper.selectSumCost(versionNo);
            PayableFeeDetailViewDAO temp1 = new PayableFeeDetailViewDAO();
            SimpleDateFormat sim = new SimpleDateFormat("yyyy-MM-dd");
            temp1.setComment(sim.format(new Date()));
            temp1.setVersionNo(versionNo);
            temp1.setAlterCost(temp.getAlterCost());
            temp1.setSysCost(temp.getSysCost());
            temp1.setSettleCost(temp.getSettleCost());
            temp1.setGoodsSum(temp.getGoodsSum());
            map.put("cost", temp1);
        }
        return map;
    }

    @Override
    public Map<String, Object> paymentList(Integer id) {
        LOGGER.info("PayableServiceImpl.paymentList params : {}, {}", id);

        if (null == id) {
            LOGGER.error("PayableServiceImpl.paymentList param  must not be null");
            throw new IllegalArgumentException("id不能为空!");
        }
        // 构建查询条件
        Map<String, Object> queryMap = new HashMap<String, Object>();
        queryMap.put("billId", id);

        // 返回值
        Map<String, Object> map = new HashMap<>();

        // 查询数据
        List<PayableFeeDetailViewDAO> payments = null;
        try {
            payments = bmsPayableFeeDetailMapper.selectPaymentList(queryMap);
        } catch (Exception e) {
            LOGGER.error("PayableServiceImpl.listPayableFeeDetails error: {}", e);
            throw new BusinessException("确认明细查询信息异常");
        }
        map.put("list", payments);

        BmsPayableBill   bill  = bmsPayableBillMapper.selectByPrimaryKey(id);
        map.put("bill", bill);

        return map;
    }

    @Override
    public int confirmPayment(PaymentBO formBo) throws Exception {
        if(formBo.getId() == null){
            LOGGER.error("PayableServiceImpl.confirmPayment param  must not be null");
            throw new IllegalArgumentException("id不能为空!");
        }
//        if(formBo.getInvoiceDate() == null){
//            LOGGER.error("PayableServiceImpl.confirmPayment param  must not be null");
//            throw new IllegalArgumentException("发票日期不能为空!");
//        }
        if(formBo.getPayDate() == null){
            LOGGER.error("PayableServiceImpl.confirmPayment param  must not be null");
            throw new IllegalArgumentException("付款日期不能为空!");
        }

        BmsPayableBill bill = new BmsPayableBill();
        BeanUtils.copyProperties(formBo , bill);
        bill.setPayStatus(PayStatusEnum.FINISH_PAY.getValue());
        bill.setModifiedUser(formBo.getUsername());
        bmsPayableBillMapper.updateByPrimaryKeySelective(bill);
        BmsPayableFeeDetailExample example = new BmsPayableFeeDetailExample();
        example.createCriteria().andBillIdEqualTo(bill.getId());
        // 根据账单获取所有运单明细id
        List<Long> detailIds = bmsPayableFeeDetailMapper.queryDetailId(bill.getId());
        // 根据账单获取所有运单id
        List<Long> wayBillIds = bmsPayableFeeDetailMapper.queryWayBillId(bill.getId());
        Set<Long> set = new HashSet();
        if (wayBillIds.size()>0) {
            wayBillIds.stream().forEach(wayBillId -> {
                // 查出该运单下所有明细运单
                CWaybillDetailExample detailExample = new CWaybillDetailExample();
                detailExample.createCriteria().andWaybillIdEqualTo(wayBillId);
                List<CWaybillDetail> details = cWaybillDetailMapper.selectByExample(detailExample);
                if (details.size()>0) {
                    details.stream().forEach(s -> {
                        if (!detailIds.contains(s.getId())) {
                            // 判断明细运单id是否存在已付款账单中，'0'表示不存在
                            Integer isId = bmsPayableFeeDetailMapper.queryIsDetailId(s.getId());
                            if (isId == 0) {
                                set.add(wayBillId);
                            }
                        }
                    });
                }
            });
        }else{
            LOGGER.error("PayableServiceImpl.confirmPayment wayBillIds  must not be null");
            throw new IllegalArgumentException("根据账单ID查询运单ID为空!");
        }
        // 移除有未付款的运单
        if (set.size()>0){
            set.stream().forEach(id ->{ wayBillIds.remove(id); });
        }
        // 批量更新运单支付状态
        if (wayBillIds.size()>0) {
            try {
                CWaybillExample waybillExample = new CWaybillExample();
                waybillExample.createCriteria().andIdIn(wayBillIds);
                CWaybill waybill = new CWaybill();
                waybill.setPayStatus(30);
                cWaybillMapper.updateByExampleSelective(waybill, waybillExample);
            } catch (Exception e) {
                throw new IllegalArgumentException("更新运单支付状态失败!");
            }
        }
        return 0;
    }

    @Override
    public Map<String, Object> selectPaymentList(PageVo pageVo, PayableBillConditions conditions) throws  Exception{
        LOGGER.info("PayableServiceImpl.selectPaymentList params : {}, {}", pageVo, conditions);

        if (null == conditions) {
            LOGGER.error("PayableServiceImpl.selectPaymentList param conditions must not be null");
            throw new IllegalArgumentException("查询条件不能为空!");
        }

        Map<String, Object> map = new HashMap<>();

        String orderByClause = null;
        if (null != pageVo) {
            orderByClause = StringUtils.isNotBlank(pageVo.getOrder()) == true ? pageVo.getOrder() : " id DESC";
        }

        BmsPayableBillExample example = new BmsPayableBillExample();
        BmsPayableBillExample.Criteria criteria = example.createCriteria();
        //账单编号
        if (null != conditions.getBillCode()) {
            criteria.andBillCodeEqualTo(conditions.getBillCode());
        }
        //承运方
        if (null != conditions.getCarrierId()) {
            criteria.andCarrierIdEqualTo(conditions.getCarrierId());
        }
        if (null != conditions.getCarrierName()) {
            criteria.andCarrierNameEqualTo(conditions.getCarrierName());
        }
        //付款状态
        if (null != conditions.getPayStatus()) {
            criteria.andPayStatusEqualTo(conditions.getPayStatus());
        }
        //账单日期
        SimpleDateFormat sim = new SimpleDateFormat("yyyy-MM-dd");
        if (null != conditions.getBillDateStart()) {
            criteria.andBillDateGreaterThanOrEqualTo(sim.parse(conditions.getBillDateStart()));
        }
        if (null != conditions.getBillDateEnd()) {
            criteria.andBillDateLessThanOrEqualTo(sim.parse(conditions.getBillDateEnd()));
        }
        //查询所有已确认，已结账的账单
        criteria.andBillStatusNotEqualTo(BillStatusEnum.NOCHECK.getValue());

        if (null != pageVo) {
            pageVo.setTotalRecord(bmsPayableBillMapper.countByExample(example));
            example.setLimitStart(pageVo.getStartIndex());
            example.setLimitEnd(pageVo.getPageSize());
            example.setOrderByClause(orderByClause);
        }

        List<BmsPayableBill> list = bmsPayableBillMapper.selectByExample(example);
        map.put("list", list);

        List<PayableFeeDetailViewDAO> nameList = null;
        try {
            nameList = cWaybillDetailMapper.selectNameByBidderId();
        } catch (Exception e) {
            LOGGER.error("PayableServiceImpl.listWaybillDetail error: {}", e);
            throw new BusinessException("查询所有承运人异常");
        }

        if(CollectionUtils.isNotEmpty(nameList)){
            map.put("carrierList", nameList);
        }

        if (null != pageVo) {
            map.put("page", pageVo);
        }

        return map;
    }


    @Override
    public void exportBillDetail(List ids, HttpServletResponse res) throws Exception {
        LOGGER.info("PayableServiceImpl.exportBillDetail params : {}, {}", ids);

        if (null == ids) {
            LOGGER.error("PayableServiceImpl.exportBillDetail param conditions must not be null");
            throw new BusinessException("账单ids不能为空!");
        }

        //添加一些数据，集合数据
        List<PayableFeeDetailViewDAO> fee = null;
        try {
            fee = bmsPayableFeeDetailMapper.selectExportDetailByIds(ids);
        } catch (Exception e) {
            LOGGER.error("PayableServiceImpl.selectPaymentList error: {}", e);
            throw new BusinessException("查询账单明细信息异常");
        }
        List listTitle = new ArrayList();
        listTitle.add("运单号");
        listTitle.add("服务订单号");
        listTitle.add("承运人");
        listTitle.add("委托日期");
        listTitle.add("运单起运地");
        listTitle.add("运单目的地");
        listTitle.add("品牌");
        listTitle.add("车系");
        listTitle.add("车架号");
        listTitle.add("数量");
        listTitle.add("状态");
        listTitle.add("采购价");
        listTitle.add("调整金额");
        listTitle.add("结算价");
        listTitle.add("客户");
        listTitle.add("订单起运地");
        listTitle.add("订单目的地");

        List<List> listData = new ArrayList<>();
        SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss");
        fee.stream().forEach(val ->{
            List data = new ArrayList();
            if (StringUtils.isNotBlank(val.getWaybillCode())) {
                data.add(val.getWaybillCode());
            }
            else data.add("");
            if (StringUtils.isNotBlank(val.getServiceOrderCode())) {
                data.add(val.getServiceOrderCode());
            }
            else data.add("");
            if (StringUtils.isNotBlank(val.getCarrierName())) {
                data.add(val.getCarrierName());
            }
            else data.add("");
            if (StringUtils.isNotBlank(format.format(val.getBillDate()))) {
                data.add(format.format(val.getBillDate()));
            }
            else data.add("");
            if (StringUtils.isNotBlank(val.getWdepartProvinceName()) && StringUtils.isNotBlank(val.getWdepartCityName())) {
                data.add(val.getWdepartProvinceName() + "-" + val.getWdepartCityName());
            }
            else data.add("");
            if (StringUtils.isNotBlank(val.getWreceiptProvinceName()) && StringUtils.isNotBlank(val.getWreceiptCityName())) {
                data.add(val.getWreceiptProvinceName() + "-" + val.getWreceiptCityName());
            }
            else data.add("");
            if (StringUtils.isNotBlank(val.getBrandName())) {
                data.add(val.getBrandName());
            }
            else data.add("");
            if (StringUtils.isNotBlank(val.getVehicleName())) {
                data.add(val.getVehicleName());
            }
            else data.add("");
            if (StringUtils.isNotBlank(val.getVin())) {
                data.add(val.getVin());
            }
            else data.add("");
            if (val.getAmount() != null) {
                data.add(val.getAmount());
            }
            else data.add("");
            if (val.getStatus() != null) {
                data.add(
                        val.getStatus() == 20 ? "已接单" :
                                (val.getStatus() == 30 ? "待提车" :
                                        (val.getStatus() == 40 ? "已提车" :
                                                (val.getStatus() == 50 ? "待发车" :
                                                        (val.getStatus() == 60 ? "待交车" :
                                                                (val.getStatus() == 80 ? "已交车" :
                                                                        (val.getStatus() == 90 ? "已完成" : "")))))));
            }
            else data.add("");
            if (val.getSysCost() != null) {
                data.add(val.getSysCost().doubleValue());
            }
            else data.add("");
            if (val.getAlterCost() != null) {
                data.add(val.getAlterCost().doubleValue());
            }
            else data.add("");
            if (val.getSettleCost() != null) {
                data.add(val.getSettleCost().doubleValue());
            }
            else data.add("");
            if (StringUtils.isNotBlank(val.getCustomerCompanyName())) {
                data.add(val.getCustomerCompanyName());
            }
            else data.add("");
            if (StringUtils.isNotBlank(val.getOdepartProvinceName()) && StringUtils.isNotBlank(val.getOdepartCityName())) {
                data.add(val.getOdepartProvinceName() + "-" + val.getOdepartCityName());
            }
            else data.add("");
            if (StringUtils.isNotBlank(val.getOreceiptProvinceName()) && StringUtils.isNotBlank(val.getOreceiptCityName())) {
                data.add(val.getOreceiptProvinceName() + "-" + val.getOreceiptCityName());
            }
            else data.add("");
            listData.add(data);
        });
        PoiUtil.exportExcel("应付账单详情", listTitle, listData, res);
    }

    @Override
    public void exportPayment(List ids, HttpServletResponse res) throws Exception{
        LOGGER.info("PayableServiceImpl.exportPayment params : {}, {}", ids);

        if (null == ids) {
            LOGGER.error("PayableServiceImpl.exportPayment param conditions must not be null");
            throw new BusinessException("账单ids不能为空!");
        }

        //添加一些数据，集合数据
        List<PayableFeeDetailViewDAO> fee = null;
        try {
            fee = bmsPayableFeeDetailMapper.selectExportDetailByIds(ids);
        } catch (Exception e) {
            LOGGER.error("PayableServiceImpl.selectPaymentList error: {}", e);
            throw new BusinessException("查询账单明细信息异常");
        }
        List listTitle = new ArrayList();
        listTitle.add("运单号");
        listTitle.add("服务订单号");
        listTitle.add("承运人");
        listTitle.add("委托日期");
        listTitle.add("运单起运地");
        listTitle.add("运单目的地");
        listTitle.add("品牌");
        listTitle.add("车系");
        listTitle.add("车架号");
        listTitle.add("数量");
        listTitle.add("状态");
        listTitle.add("采购价");
        listTitle.add("调整金额");
        listTitle.add("结算价");
        listTitle.add("客户");
        listTitle.add("订单起运地");
        listTitle.add("订单目的地");
        listTitle.add("收款状态");
        listTitle.add("销售价");

        List<List> listData = new ArrayList<>();
        SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss");
        fee.stream().forEach(val ->{
            List data = new ArrayList();
            if (StringUtils.isNotBlank(val.getWaybillCode())) {
                data.add(val.getWaybillCode());
            }
            else data.add("");
            if (StringUtils.isNotBlank(val.getServiceOrderCode())) {
                data.add(val.getServiceOrderCode());
            }
            else data.add("");
            if (StringUtils.isNotBlank(val.getCarrierName())) {
                data.add(val.getCarrierName());
            }
            else data.add("");
            if (StringUtils.isNotBlank(format.format(val.getBillDate()))) {
                data.add(format.format(val.getBillDate()));
            }
            else data.add("");
            if (StringUtils.isNotBlank(val.getWdepartProvinceName()) && StringUtils.isNotBlank(val.getWdepartCityName())) {
                data.add(val.getWdepartProvinceName() + "-" + val.getWdepartCityName());
            }
            else data.add("");
            if (StringUtils.isNotBlank(val.getWreceiptProvinceName()) && StringUtils.isNotBlank(val.getWreceiptCityName())) {
                data.add(val.getWreceiptProvinceName() + "-" + val.getWreceiptCityName());
            }
            else data.add("");
            if (StringUtils.isNotBlank(val.getBrandName())) {
                data.add(val.getBrandName());
            }
            else data.add("");
            if (StringUtils.isNotBlank(val.getVehicleName())) {
                data.add(val.getVehicleName());
            }
            else data.add("");
            if (StringUtils.isNotBlank(val.getVin())) {
                data.add(val.getVin());
            }
            else data.add("");
            if (val.getAmount() != null) {
                data.add(val.getAmount());
            }
            else data.add("");
            if (val.getStatus() != null) {
                data.add(
                        val.getStatus() == 20 ? "已接单" :
                                (val.getStatus() == 30 ? "待提车" :
                                        (val.getStatus() == 40 ? "已提车" :
                                                (val.getStatus() == 50 ? "待发车" :
                                                        (val.getStatus() == 60 ? "待交车" :
                                                                (val.getStatus() == 80 ? "已交车" :
                                                                        (val.getStatus() == 90 ? "已完成" : "")))))));
            }
            else data.add("");
            if (val.getSysCost() != null) {
                data.add(val.getSysCost().doubleValue());
            }
            else data.add("");
            if (val.getAlterCost() != null) {
                data.add(val.getAlterCost().doubleValue());
            }
            else data.add("");
            if (val.getSettleCost() != null) {
                data.add(val.getSettleCost().doubleValue());
            }
            else data.add("");
            if (StringUtils.isNotBlank(val.getCustomerCompanyName())) {
                data.add(val.getCustomerCompanyName());
            }
            else data.add("");
            if (StringUtils.isNotBlank(val.getOdepartProvinceName()) && StringUtils.isNotBlank(val.getOdepartCityName())) {
                data.add(val.getOdepartProvinceName() + "-" + val.getOdepartCityName());
            }
            else data.add("");
            if (StringUtils.isNotBlank(val.getOreceiptProvinceName()) && StringUtils.isNotBlank(val.getOreceiptCityName())) {
                data.add(val.getOreceiptProvinceName() + "-" + val.getOreceiptCityName());
            }
            else data.add("");
            if (val.getPayStatus() != null) {
                data.add(
                        val.getPayStatus() == 10 ? "未付款" :
                                (val.getPayStatus() == 20 ? "部分付款" :
                                        (val.getPayStatus() == 30 ? "付款完成" :val.getPayStatus().toString())));
            }
            else data.add("");
            if (val.getCost() != null) {
                data.add(val.getCost().doubleValue());
            }
            else data.add("");
            listData.add(data);
        });
        PoiUtil.exportExcel("应付账单详情", listTitle, listData, res);

    }
}

